package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.query.DestinationQuery;
import cn.wolfcode.wolf2w.repository.DestinationRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IRegionService;
import cn.wolfcode.wolf2w.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
//@Transactional
public class DestinationServiceImpl implements IDestinationService {
	@Autowired
	private MongoTemplate template;
	@Autowired
	private DestinationRepository destinationRepository;
	@Autowired
	private IRegionService regionService;

	@Override
	public void save(Destination destination) {
		destinationRepository.save(destination);
	}

	@Override
	public void update(Destination destination) {
		destinationRepository.save(destination);
	}

	@Override
	public void delete(String id) {
		destinationRepository.deleteById(id);
	}

	@Override
	public Destination get(String id) {
		return destinationRepository.findById(id).orElse(null);
	}

	@Override
	public List<Destination> search(String regionId) {
		List<Destination> destinations;

		// 判断是国外还是国内,-1是国内
		if ("-1".equals(regionId)) {
			// 查询父级是国内的目的地
			destinations = destinationRepository.findByParentName("中国");
		} else {
			// 根据传入的国外区域id查询关联的目的地
			destinations = this.queryDestByRegionId(regionId);
		}

		for (Destination destination : destinations) {
			// 根据父级id查询子目的地
			Query query = new Query();
			// 显示5条数据
			query.addCriteria(Criteria.where("parentId").is(destination.getId()));
			query.with(PageRequest.of(0,5));
			List<Destination> children = template.find(query, Destination.class);
			// 把子目的地集合赋值给 children属性
			destination.setChildren(children);
		}

		return destinations;
	}

	@Override
	public void updateInfo(String id, String info) {
		Query query = new Query();
		query.addCriteria(Criteria.where("_id").is(id));

		Update update = new Update();
		update.set("info", info);

		template.updateMulti(query, update, Destination.class);
	}

	@Override
	public List<Destination> queryParent(List<Destination> destinations, String parentId) {
		if (!StringUtils.hasLength(parentId)) {
			return destinations;
		}
		// 第一次执行时传入id查询到当前点击的目的地
		// 第二次之后的执行时传入被点击的祖辈的id
		Destination destination = this.get(parentId);
		// 把查询出来的对象添加到集合中
		destinations.add(destination);
		// 父级的id不为空才执行
		if (StringUtils.hasLength(destination.getParentId())) {
			// destinations 存储被点击目的地的 id和它祖辈的id
			queryParent(destinations, destination.getParentId());
		}
		return destinations;
	}


	@Override
	public Page query(DestinationQuery qo) {
		Query query = new Query();
		// 判断用户是否进行高级查询
		if (StringUtils.hasLength(qo.getKeyword())) {
			query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
		}

		if (StringUtils.hasLength(qo.getParentId())) {
			query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
		} else {
			query.addCriteria(Criteria.where("parentId").is(null));
		}
		// 调用分页工具类
		// 需要传入 MongoTemplate对象,
		// 拼接MQL语句的对象,
		// 操作的表 -> 实体类,
		// qo,
		// 根据什么列排序
		return PageUtils.page(template, query, Destination.class, qo,Sort.by(Sort.Direction.ASC,"_id"));
	}

	@Override
	public List<Destination> list() {
		return destinationRepository.findAll();
	}

	@Override
	public List<Destination> queryDestByRegionId(String rid) {
		// 根据地区 id查询关联的目的地
		List<String> destByRegionIds = regionService.getDestByRegionId(rid);
		return destinationRepository.findByIdIn(destByRegionIds);
	}

	@Override
	public List<Destination> getDestByDeep(int deep) {
		return destinationRepository.findByDeep(deep);
	}

	@Override
	public Destination findByName(String name) {
		return destinationRepository.findByName(name);
	}
}
